/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.xuexiang.xui_lib.component.grouplist;

import ohos.agp.colors.RgbColor;
import ohos.agp.colors.RgbPalette;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentState;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.app.Context;

import com.xuexiang.xui_lib.util.DisplayUtils;
import com.xuexiang.xui_lib.util.TypedAttrUtils;
import com.xuexiang.xui_lib.util.ViewUtils;

import java.util.HashMap;

/**
 * 通用的列表, 常用于 App 的设置界面。
 * <p>
 * 注意其父类不是 {@link ohos.agp.components.ListContainer}, 而是 {@link DirectionalLayout},
 * 一般需要在外层包多一个 {@link ohos.agp.components.ScrollView} 来支持滚动。
 * </p>
 * <p>
 * 提供了 {@link Section} 的概念, 用来将列表分块。 具体见 {@link Section}
 * </p>
 * <p>
 * usage:
 * <pre>
 *         XUIGroupListView groupListView = new XUIGroupListView(context);
 *         // section 1
 *         XUIGroupListView.newSection(context)
 *                 .setTitle("Section Title 1")
 *                 .setDescription("这是Section 1的描述")
 *                 .addItemView(groupListView.createItemView("item 1"), new OnClickListener() {
 *                     {@literal @}Override
 *                     public void onClick(View v) {
 *                         Toast.makeText(context, "section 1 item 1", Toast.LENGTH_SHORT).show();
 *                     }
 *                 })
 *                 .addItemView(groupListView.createItemView("item 2"), new OnClickListener() {
 *                     {@literal @}verride
 *                     public void onClick(View v) {
 *                         Toast.makeText(context, "section 1 item 2", Toast.LENGTH_SHORT).show();
 *                     }
 *                 })
 *                 // 设置分隔线的样式
 *                 .setSeparatorDrawableRes(
 *                         R.drawable.list_group_item_single_bg,
 *                         R.drawable.personal_list_group_item_top_bg,
 *                         R.drawable.list_group_item_bottom_bg,
 *                         R.drawable.personal_list_group_item_middle_bg)
 *                 // 如果没有title,加上默认title【Section n】
 *                 .setUseDefaultTitleIfNone(true)
 *                 // 默认使用TitleView的padding作section分隔,可以设置为false取消它
 *                 .setUseTitleViewForSectionSpace(false)
 *                 .addTo(groupListView);
 *
 *         // section 2
 *         XUIGroupListView.newSection(context)
 *                 .setTitle("Section Title 2")
 *                 .setDescription("这是Section 2的描述")
 *                 .addItemView(groupListView.createItemView("item 1"), new OnClickListener() {
 *                     {@literal @}@Override
 *                     public void onClick(View v) {
 *                         Toast.makeText(context, "section 2 item 1", Toast.LENGTH_SHORT).show();
 *                     }
 *                 })
 *                 .addItemView(groupListView.createItemView("item 2"), new OnClickListener() {
 *                     {@literal @}Override
 *                     public void onClick(View v) {
 *                         Toast.makeText(context, "section 2 item 2", Toast.LENGTH_SHORT).show();
 *                     }
 *                 })
 *                 .addTo(groupListView);
 * </pre>
 *
 * @author xuexiang
 * @since 2019/1/3 上午10:24
 */
public class XUIGroupListView extends DirectionalLayout {
    private static final int verticalItemHeight = 103;
    private static final int horizontalItemHeight = 56;

    private AttrSet attrs;
    private HashMap<Integer, Section> mSections;

    public XUIGroupListView(Context context) {
        this(context, null, null);
    }

    public XUIGroupListView(Context context, AttrSet attrs) {
        this(context, attrs, null);
    }

    public XUIGroupListView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs);
        this.attrs = attrs;

        mSections = new HashMap<>();
        setOrientation(DirectionalLayout.VERTICAL);
    }

    /**
     * 创建一个 Section。
     *
     * @param context
     * @return Section
     */
    public static Section newSection(Context context) {
        return new Section(context);
    }

    public int getSectionCount() {
        return mSections.size();
    }

    public XUICommonListItemView createItemView(int image, String titleText,
                                                String detailText, int orientation, int accessoryType, int height) {
        XUICommonListItemView itemView = new XUICommonListItemView(getContext(), attrs);
        itemView.setOrientation(orientation);
        itemView.setLayoutConfig(new LayoutConfig(LayoutConfig.MATCH_PARENT, DisplayUtils.vp2px(getContext(), height)));
        itemView.setImageElement(image);
        itemView.setText(titleText);
        itemView.setDetailText(detailText);
        itemView.setAccessoryType(accessoryType);
        return itemView;
    }

    public XUICommonListItemView createItemView(int image, String titleText,
                                                String detailText, int orientation, int accessoryType) {
        int height;
        if (orientation == XUICommonListItemView.VERTICAL) {
            height = TypedAttrUtils.getDimensionPixelSize(attrs, "xui_list_item_height_higher", verticalItemHeight);
        } else {
            height = TypedAttrUtils.getDimensionPixelSize(attrs, "xui_list_item_height", horizontalItemHeight);
        }
        return createItemView(image, titleText, detailText, orientation, accessoryType, height);
    }

    public XUICommonListItemView createItemView(String titleText) {
        return createItemView(0, titleText, null,
            XUICommonListItemView.HORIZONTAL, XUICommonListItemView.ACCESSORY_TYPE_NONE);
    }

    public XUICommonListItemView createItemView(int orientation) {
        return createItemView(0, null,
            null, orientation, XUICommonListItemView.ACCESSORY_TYPE_NONE);
    }

    /**
     * private, use {@link Section#addTo(XUIGroupListView)}
     * <p>这里只是把section记录到数组里面而已</p>
     *
     * @param section
     */
    private void addSection(Section section) {
        mSections.put(mSections.size(), section);
    }

    /**
     * private，use {@link Section#removeFrom(XUIGroupListView)}
     * <p>这里只是把section从记录的数组里移除而已</p>
     *
     * @param section
     */
    private void removeSection(Section section) {
        for (int i = 0; i < mSections.size(); i++) {
            Section each = mSections.get(i);
            if (each == section) {
                mSections.remove(i);
            }
        }
    }

    public Section getSection(int index) {
        return mSections.get(index);
    }

    /**
     * Section 是组成 {@link XUIGroupListView} 的部分。
     * <ul>
     * <li>每个 Section 可以有多个 item, 通过 {@link #addItemView(XUICommonListItemView, ClickedListener)} 添加。</li>
     * <li>Section 还可以有自己的一个顶部 title 和一个底部 description, 通过 {@link #setTitle(String)}
     * 和 {@link #setDescription(String)} 设置。</li>
     * </ul>
     */
    public static class Section {
        private Context mContext;
        private XUIGroupListSectionHeaderFooterView mTitleView;
        private XUIGroupListSectionHeaderFooterView mDescriptionView;
        private HashMap<Integer, XUICommonListItemView> mItemViews;
        private boolean isUseDefaultTitleIfNone;
        private boolean isUseTitleViewForSectionSpace = true;
        private int mLeftIconWidth = ComponentContainer.LayoutConfig.MATCH_CONTENT;
        private int mLeftIconHeight = ComponentContainer.LayoutConfig.MATCH_CONTENT;

        public Section(Context context) {
            mContext = context;
            mItemViews = new HashMap<>();
        }

        /**
         * 对 Section 添加一个 {@link XUICommonListItemView}
         *
         * @param itemView 要添加的 ItemView
         * @param onClickListener ItemView 的点击事件
         * @return Section 本身,支持链式调用
         */
        public Section addItemView(XUICommonListItemView itemView,
                                   Component.ClickedListener onClickListener) {
            return addItemView(itemView, onClickListener, null);
        }

        /**
         * 对 Section 添加一个 {@link XUICommonListItemView}
         *
         * @param itemView 要添加的 ItemView
         * @param onClickListener ItemView 的点击事件
         * @param onLongClickListener ItemView 的长按事件
         * @return Section 本身, 支持链式调用
         */
        public Section addItemView(final XUICommonListItemView itemView,
                                   Component.ClickedListener onClickListener,
                                   Component.LongClickedListener onLongClickListener) {
            // 如果本身带有开关控件，点击item时要改变开关控件的状态（开关控件本身已经disable掉）
            if (itemView.getAccessoryType() == XUICommonListItemView.ACCESSORY_TYPE_SWITCH) {
                itemView.setClickedListener(new ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        itemView.getSwitch().toggle();
                    }
                });
            } else if (onClickListener != null) {
                itemView.setClickedListener(onClickListener);
            }

            if (onLongClickListener != null) {
                itemView.setLongClickedListener(onLongClickListener);
            }

            mItemViews.put(mItemViews.size(), itemView);
            return this;
        }

        /**
         * 设置 Section 的 title
         *
         * @param title
         * @return Section
         */
        public Section setTitle(String title) {
            mTitleView = createSectionHeader(title);
            return this;
        }

        /**
         * 设置 Section 的 description
         *
         * @param description
         * @return Section
         */
        public Section setDescription(String description) {
            mDescriptionView = createSectionFooter(description);
            return this;
        }

        public Section setUseDefaultTitleIfNone(boolean isUse) {
            this.isUseDefaultTitleIfNone = isUse;
            return this;
        }

        public Section setUseTitleViewForSectionSpace(boolean isUse) {
            isUseTitleViewForSectionSpace = isUse;
            return this;
        }

        public Section setLeftIconSize(int width, int height) {
            mLeftIconHeight = height;
            mLeftIconWidth = width;
            return this;
        }

        /**
         * 将 Section 添加到 {@link XUIGroupListView} 上
         *
         * @param groupListView
         */
        public void addTo(XUIGroupListView groupListView) {
            if (mTitleView == null) {
                if (isUseDefaultTitleIfNone) {
                    setTitle("Section " + groupListView.getSectionCount());
                } else if (isUseTitleViewForSectionSpace) {
                    setTitle("");
                }
            }
            if (mTitleView != null) {
                groupListView.addComponent(mTitleView);
            }

            final int itemViewCount = mItemViews.size();
            XUICommonListItemView.LayoutParamConfig leftIconLpConfig = new XUICommonListItemView.LayoutParamConfig() {
                @Override
                public DependentLayout.LayoutConfig onConfig(DependentLayout.LayoutConfig lc) {
                    lc.width = mLeftIconWidth;
                    lc.height = mLeftIconHeight;
                    return lc;
                }
            };
            for (int i = 0; i < itemViewCount; i++) {
                XUICommonListItemView itemView = mItemViews.get(i);
                itemView.updateImageViewLc(leftIconLpConfig);
                StateElement stateElement = new StateElement();
                ShapeElement pressedElement = (ShapeElement) groupListView.getBackgroundElement();
                stateElement.addState(new int[]{ComponentState.COMPONENT_STATE_PRESSED}, pressedElement);
                ShapeElement normalElement = new ShapeElement();
                normalElement.setRgbColor(RgbPalette.WHITE);
                stateElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, normalElement);
                ViewUtils.setBackgroundKeepingPadding(itemView, stateElement);
                groupListView.addComponent(itemView);
            }

            if (mDescriptionView != null) {
                groupListView.addComponent(mDescriptionView);
            }
            groupListView.addSection(this);
        }

        public void removeFrom(XUIGroupListView parent) {
            if (mTitleView != null && mTitleView.getComponentParent() == parent) {
                parent.removeComponent(mTitleView);
            }
            for (int i = 0; i < mItemViews.size(); i++) {
                XUICommonListItemView itemView = mItemViews.get(i);
                parent.removeComponent(itemView);
            }
            if (mDescriptionView != null && mDescriptionView.getComponentParent() == parent) {
                parent.removeComponent(mDescriptionView);
            }
            parent.removeSection(this);
        }

        /**
         * 创建 Section Header，每个 Section 都会被创建一个 Header，有 title 时会显示 title，
         * 没有 title 时会利用 header 的上下 padding 充当 Section 分隔条
         *
         * @param titleText
         * @return XUIGroupListSectionHeaderFooterView
         */
        public XUIGroupListSectionHeaderFooterView createSectionHeader(String titleText) {
            return new XUIGroupListSectionHeaderFooterView(mContext, titleText);
        }

        /**
         * Section 的 Footer，形式与 Header 相似，都是显示一段文字
         *
         * @param text
         * @return XUIGroupListSectionHeaderFooterView
         */
        public XUIGroupListSectionHeaderFooterView createSectionFooter(String text) {
            return new XUIGroupListSectionHeaderFooterView(mContext, text, true);
        }
    }
}
